package com.link.base.base.sms.service;

import com.github.qcloudsms.SmsMultiSender;
import com.github.qcloudsms.SmsMultiSenderResult;
import com.link.base.sms.model.*;
import com.link.base.user.model.CoreUser;
import com.link.base.base.sms.dao.mybatis.mapper.*;
import com.link.base.base.sms.model.SendSmsAccount;
import com.link.base.base.sms.model.SmsAccntLineDTO;
import com.link.core.cllog.LCLogger;
import com.link.base.loyalty.member.model.Member;
import com.link.core.basic.dao.KeyGenerateDao;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.service.BasicServiceImpl;
import com.link.core.util.SendSmsUtil;
import com.link.core.util.SessionUtil;
import com.link.core.util.StringUtils;
import com.link.core.util.UserUtil;
import com.link.base.base.sms.dao.mybatis.mapper.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author: liulu
 * @Date:15:37 2018/11/5
 */

@Service
public class SmsSendServiceImpl extends BasicServiceImpl<SmsSend> implements SmsSendService {

    @Resource
    private SmsSendMapper smsSendMapper;
    @Resource
    private SendSmsAccountService sendSmsAccountService;
    @Resource
    private SendSmsAccountMapper sendSmsAccountMapper;
    @Resource
    private TemplateMapper templateMapper;
    @Resource
    private SendResultMapper sendResultMapper;
    @Resource
    private SmsAccntLineMapper smsAccntLineMapper;
    @Resource
    private TemparameterService temparameterService;
    @Resource
    private SmsAccntLineService smsAccntLineService;

    @Resource
    private KeyGenerateDao keyGenerateDao;

    @Override
    public BasicMapper<SmsSend> getBasicMapper() {
        return smsSendMapper;
    }


    @Override
    public Long insertSms(SmsSend entity) throws Exception {
        CoreUser user = UserUtil.getUser();
        entity.setId(keyGenerateService.keyGenerate());
        entity.setOrgId(user.getOrgId());
        entity.setPostnId(user.getPostnId());
        smsSendMapper.insert(entity);
        SessionUtil.setAttribute("SendSmsId", entity.getId().toString());
        return entity.getId();
    }


    /**
     * @author liulu
     * @zhushi: 把客户与短信关联
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addSendAccont(SmsSend entity) {
        List<SmsAccntLine> smsList = entity.getSmsAccntLineList();
        SendSmsAccount sendSmsAccount = new SendSmsAccount();
        sendSmsAccount.setSmsId(entity.getId());
        for (SmsAccntLine smsAccntLine : smsList) {
            sendSmsAccount.setId(keyGenerateDao.keyGenerate());
            sendSmsAccount.setAccountId(smsAccntLine.getId());
            try {
                sendSmsAccountService.insert(sendSmsAccount);
            } catch (Exception e) {
                LCLogger.withException(e);
            }
        }
    }

    /**
     * @author liulu
     * @zhushi: 把客户与短信关联
     */
    @Override
    public void addSendAccontLine(Long sendSmsId, Long accoutId) {
        SendSmsAccount sendSmsAccount = new SendSmsAccount();
        sendSmsAccount.setAccountId(accoutId);
        sendSmsAccount.setSmsId(sendSmsId);

        try {
            sendSmsAccountService.insert(sendSmsAccount);
        } catch (Exception e) {
            LCLogger.withException(e);
        }


    }

    /**
     * @author liulu
     * @zhushi: 把客户与短信关联
     */
    @Override
    public void addSendAccontLineNew(Long sendSmsId, Long accoutId, Long corpid) {
        SendSmsAccount sendSmsAccount = new SendSmsAccount();
        sendSmsAccount.setAccountId(accoutId);
        sendSmsAccount.setSmsId(sendSmsId);
        sendSmsAccount.setCorpid(corpid);
        sendSmsAccount.setLoginCorpId(corpid);
        sendSmsAccount.setAnonymousFlag("Y");
        sendSmsAccount.setPostnId(0L);
        try {
            sendSmsAccountService.insert(sendSmsAccount);
        } catch (Exception e) {
            LCLogger.withException(e);
        }


    }


    /**
     * @author liulu
     * @zhushi: 短信定时发送
     */
    @Override
    public void isSendSms() {
        try {
            List<SmsSend> list = smsSendMapper.queryByFutureTXT();
            for (SmsSend smsSend2 : list) {
                this.sendSms(smsSend2);
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            LCLogger.withException(e);
        }

    }

    @Override
    public int querCountByAccn(Long smsId) {
        return smsSendMapper.querCountByAccn(smsId);
    }

    /**
     * @author liulu
     * @param smsSend 发送短信 corpid templateId temparameterId
     */
    @Override
    public void sendSms(SmsSend smsSend) {
        sendSms(smsSend, null);
    }

    /**
     * 注册会员短信发送
     * @author 顾桂山
     * @param smsSend 短信
     * @param member
     */
    @Override
    public void sendSms(SmsSend smsSend, Member member) {
        Long corpid;
        if (null != smsSend.getCorpid()) {
            corpid = smsSend.getCorpid();
        } else {
            corpid = UserUtil.getUser().getCorpid();
        }
        Template te = new Template();
        te.setLoginCorpId(corpid);
        te.setCorpid(corpid);
        te.setId(smsSend.getTemplateId());
        Temparameter par = new Temparameter();
        par.setLoginCorpId(corpid);
        par.setCorpid(corpid);
        par.setId(smsSend.getTemparameterId());
        try {
            SmsAccntLine accn = new SmsAccntLine();
            accn.setxAttr64(smsSend.getId().toString());
            accn.setPageFlag(false);
            accn.setCorpid(corpid);
            accn.setLoginCorpId(corpid);
            List<SmsAccntLine> acc = smsAccntLineMapper.queryBySendSmsIdExamplePage(accn);
            smsSend.setSmsAccntLineList(acc);
            Template template = templateMapper.queryById(te);
            smsSend.setTemplate(template);
            Temparameter ee = temparameterService.queryById(par);
            smsSend.setTemparameter(ee);

            List<SendResult> sendSms = null;
            if (member == null) {
                sendSms = SendSmsUtil.sendSms(smsSend);
            } else {
                List<Member> memberList = new ArrayList<>();
                memberList.add(member);
                sendSms = sendMemberSms(smsSend, memberList);
            }

            int sendCount = 0;
            int sendCountwin = 0;
            int useCountwin = sendSms.size();
            for (SendResult sendResult : sendSms) {
                sendResult.setId(keyGenerateService.keyGenerate());
                sendResult.setLoginCorpId(corpid);
                sendResult.setLoginCorpId(corpid);
                sendResult.setPostnId(0L);
                sendResult.setOrgId(0L);
                sendResultMapper.insert(sendResult);
                sendCount += sendResult.getFee();
                if (sendResult.getResult() != 0) {
                    sendCountwin -= sendResult.getFee();
                    useCountwin -= 1;
                }
            }
            // 更新短信结果
            smsSend.setSendCount(sendCount);
            smsSend.setSendCountWin(sendCount + sendCountwin);
            smsSend.setSendPeopleWin(useCountwin);
            smsSend.setCorpid(corpid);
            smsSend.setLoginCorpId(corpid);
            smsSend.setAnonymousFlag("Y");
            if ((sendCount + sendCountwin) > 0) {
                smsSend.setSendState("Succeeded");
            } else {
                smsSend.setSendState("Failed");
            }
            smsSendMapper.update(smsSend);
        } catch (Exception e) {
            LCLogger.withException(e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addSendAcctRemoveDup(SmsAccntLineDTO smsAccntLineDTO, Long sendSmsId, int rows) throws Exception {
        Set<String> telSet = new HashSet<>();
        List<SmsAccntLine> smsList;
        AtomicInteger count = new AtomicInteger();
        SendSmsAccount smsAccount = new SendSmsAccount();
        smsAccount.setSmsId(sendSmsId);

        //分页查询客户，写入短信客户中间表
        smsAccntLineDTO.setPage(0);
        smsAccntLineDTO.setRows(rows);
        smsAccntLineDTO.setPageFlag(true);
        smsAccntLineDTO.setTotalFlag(true);
        //清除短信客户中间表关系 防止数据重复
        this.delBySmsId(sendSmsId);
        do {
            smsAccntLineDTO.setPage(smsAccntLineDTO.getPage() + 1);
            smsList = smsAccntLineService.queryByFiltrateExamplePage(smsAccntLineDTO);
            for (SmsAccntLine item : smsList) {
                boolean notExists = telSet.add(item.getMobilePhone1());
                if (notExists) {
                    smsAccount.setId(keyGenerateService.keyGenerate());
                    smsAccount.setAccountId(item.getId());
                    sendSmsAccountService.insert(smsAccount);
                    count.getAndIncrement();
                }
            }
            smsList.clear();
        }
        while (smsAccntLineDTO.getTotal() > smsAccntLineDTO.getEndRow());
        telSet.clear();
        return count.get();
    }

    /**
     * sms信息发送
     * @param smsSend
     * @param memberList accountId mobilePhone
     * @return
     */
    private List<SendResult> sendMemberSms(SmsSend smsSend, List<Member> memberList) {
        List<SendResult> resus = new ArrayList();
        if (memberList == null || memberList.isEmpty()) {
            return resus;
        }
        SendResult sendResult = null;
        ArrayList<String> params = new ArrayList();
        Template template = smsSend.getTemplate();
        Temparameter temparameter = smsSend.getTemparameter();

        boolean paramExistFlag = true;
        if (!StringUtils.isNull(temparameter.getParameter1())) {
            params.add(temparameter.getParameter1());
        } else {
            paramExistFlag = false;
        }

        if (paramExistFlag && !StringUtils.isNull(temparameter.getParameter2())) {
            params.add(temparameter.getParameter2());
        } else {
            paramExistFlag = false;
        }

        if (paramExistFlag && !StringUtils.isNull(temparameter.getParameter3())) {
            params.add(temparameter.getParameter3());
        } else {
            paramExistFlag = false;
        }

        if (paramExistFlag && !StringUtils.isNull(temparameter.getParameter4())) {
            params.add(temparameter.getParameter4());
        } else {
            paramExistFlag = false;
        }

        if (paramExistFlag && !StringUtils.isNull(temparameter.getParameter5())) {
            params.add(temparameter.getParameter5());
        } else {
            paramExistFlag = false;
        }

        if (paramExistFlag && !StringUtils.isNull(temparameter.getParameter6())) {
            params.add(temparameter.getParameter6());
        } else {
            paramExistFlag = false;
        }

        if (paramExistFlag && !StringUtils.isNull(temparameter.getParameter7())) {
            params.add(temparameter.getParameter7());
        } else {
            paramExistFlag = false;
        }

        if (paramExistFlag && !StringUtils.isNull(temparameter.getParameter8())) {
            params.add(temparameter.getParameter8());
        } else {
            paramExistFlag = false;
        }

        if (paramExistFlag && !StringUtils.isNull(temparameter.getParameter9())) {
            params.add(temparameter.getParameter9());
        } else {
            paramExistFlag = false;
        }

        if (paramExistFlag && !StringUtils.isNull(temparameter.getParameter10())) {
            params.add(temparameter.getParameter10());
        }

        ArrayList<String> phoneNumbers = new ArrayList();
        for (Member member : memberList) {
            phoneNumbers.add(member.getMobilePhone());
        }
        if (memberList.size() > 1) {
            try {
                SmsMultiSender multiSender = new SmsMultiSender(1400029749, "9a7f73691ec83dd1691a3266d5205d23");
                SmsMultiSenderResult sendWithParam = multiSender.sendWithParam("86", phoneNumbers, template.getTemplID().intValue(), params, smsSend
                        .getSigText(), smsSend.getExtend(), smsSend.getExt());

                for (SmsMultiSenderResult.Detail detail : sendWithParam.details) {
                    for (Member member : memberList) {
                        if (StringUtils.equals(detail.phoneNumber, member.getMobilePhone())) {
                            sendResult = new SendResult(detail.result, detail.errMsg, detail.fee, detail.phoneNumber, detail.nationCode, detail
                                    .sid, smsSend.getId(), sendWithParam.ext, member.getAccountId(), null, getRequestStatus(detail.result));
                            resus.add(sendResult);
                        }
                    }
                }
            } catch (Exception e) {
                LCLogger.withException(e);
            }
        } else {
            try {
                com.github.qcloudsms.SmsSingleSender sender = new com.github.qcloudsms.SmsSingleSender(1400029749,
                        "9a7f73691ec83dd1691a3266d5205d23");
                com.github.qcloudsms.SmsSingleSenderResult result = sender.sendWithParam("86", (String) phoneNumbers.get(0), template.getTemplID()
                        .intValue(), params, smsSend.getSigText(), smsSend.getExtend(), smsSend.getExt());

                for (Member member : memberList) {
                    sendResult = new SendResult(result.result, result.errMsg, result.fee, (String) phoneNumbers.get(0), "86", result.sid, smsSend
                            .getId(), result.ext, member.getAccountId(), null, getRequestStatus(result.result));
                    resus.add(sendResult);
                }
            } catch (Exception e) {
                LCLogger.withException(e);
            }
        }

        return resus;
    }

    @Override
    public void delBySmsId(Long smsId) {
        SendSmsAccount smsSend = new SendSmsAccount();
        smsSend.setSmsId(smsId);
        sendSmsAccountMapper.delBySmsId(smsSend);
    }

    public static String getRequestStatus(int idex) {
        String requestStatus;
        if (0 == idex) {
            requestStatus = "SUCCESS";
        } else {
            requestStatus = "FAIL";
        }
        return requestStatus;
    }
}
